package net.yunzhanyi.client.service.impl;

import eu.bitwalker.useragentutils.UserAgent;
import net.yunzhanyi.client.constant.AccountConstant;
import net.yunzhanyi.client.constant.LoginConstant;
import net.yunzhanyi.client.domain.dto.ClientLoginUser;
import net.yunzhanyi.client.service.LoginService;
import net.yunzhanyi.client.service.TokenService;
import net.yunzhanyi.common.core.exception.BaseException;
import net.yunzhanyi.common.core.utils.ObjectUtils;
import net.yunzhanyi.common.core.utils.StringUtils;
import net.yunzhanyi.common.web.util.AddressUtils;
import net.yunzhanyi.common.web.util.IPUtils;
import net.yunzhanyi.common.web.util.ServletUtils;
import net.yunzhanyi.common.web.util.encoder.PasswordEncoder;
import net.yunzhanyi.generic.domain.model.ClientAccount;
import net.yunzhanyi.generic.domain.model.ClientUser;
import net.yunzhanyi.generic.mapper.ClientAccountMapper;
import net.yunzhanyi.generic.mapper.ClientUserMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;

/**
 * @author bestct
 * @date 2022/10/1
 * @type 类
 */
@Service
public class LoginServiceImpl implements LoginService {


    @Autowired
    private ClientAccountMapper clientAccountMapper;

    @Autowired
    private ClientUserMapper clientUserMapper;


    @Autowired
    public TokenService tokenService;

    @Autowired
    PasswordEncoder passwordEncoder;

    /**
     * 账号密码登录
     *
     * @param accountNumber
     * @param password
     * @return token
     */
    @Override
    public ClientLoginUser login(String accountNumber, String password) {
        //判断是否为空
        if (StringUtils.isEmpty(accountNumber) || StringUtils.isEmpty(password)) {
            throw new BaseException(LoginConstant.EMPTY);
        }

        //登录账号有两种
        ClientAccount account = null;
        if (StringUtils.isMobile(accountNumber)) {
            account = clientAccountMapper.selectByPhone(accountNumber);
        } else if (StringUtils.isEmail(accountNumber)) {
            account = clientAccountMapper.selectByEmail(accountNumber);
        } else {
            throw new BaseException(LoginConstant.LOGIN_FAIL);
        }

        //判断是否为空
        if (ObjectUtils.isNull(account) || ObjectUtils.isNull(account.getAid())) {
            throw new BaseException(LoginConstant.LOGIN_FAIL);
        }
        if (!account.getStatus().equals(AccountConstant.ACTIVE)) {
            throw new BaseException(LoginConstant.ACCOUNT_ERROR);
        }
        //比对密码
        if (!passwordEncoder.matches(password, account.getPassword())) {
            throw new BaseException(LoginConstant.LOGIN_FAIL);
        }
        return createClientLoginUser(account.getAid());
    }


    @Override
    public void logout() {
        HttpServletRequest request = ServletUtils.getRequest();
        assert request != null;
        String token = tokenService.getToken(request);
        tokenService.deleteToken(token);
    }

    @Override
    public void webLogout() {
        HttpServletRequest request = ServletUtils.getRequest();
        assert request != null;
        String token = tokenService.getWebToken(request);
        tokenService.deleteToken(token);
    }

    private ClientLoginUser createClientLoginUser(Long aid) {
        ClientUser clientUser = clientUserMapper.selectByPrimaryKey(aid);
        ClientLoginUser clientLoginUser = new ClientLoginUser();
        BeanUtils.copyProperties(clientUser, clientLoginUser);
        setUserAgent(clientLoginUser);
        return clientLoginUser;
    }


    /**
     * 设置用户代理信息
     *
     * @param loginUser 登录信息
     */
    public void setUserAgent(ClientLoginUser loginUser) {
        UserAgent userAgent = UserAgent.parseUserAgentString(ServletUtils.getRequest().getHeader("User-Agent"));
        String ip = IPUtils.getIpAddress(ServletUtils.getRequest());
        loginUser.setIpaddr(ip);
        loginUser.setLoginLocation(AddressUtils.getRealAddressByIP(ip));
        loginUser.setBrowser(userAgent.getBrowser().getName());
        loginUser.setOs(userAgent.getOperatingSystem().getName());
    }

}
